/**
 * 流程图只读模式
 */
import { useForm } from "../../framework/common/context/metadata-context";
import {getQuery} from "../../framework/common/utils"
import "./approveStepReadonly.css"
import Operations from "./Operations";//只读模式右上角3个按钮
import React, { useRef, useState } from "react";
import clsx from "clsx";
import { Tooltip , Input, Radio, Space, Checkbox, Spin, Skeleton } from "antd";
import get from "lodash/get";
import {v4 as uuid} from 'uuid'
import { InjectProvider, useInject } from "../../framework/common/context/inject-context";

//编辑模式的依赖项
import { useUpdate } from "ahooks";
import message from "../../framework/common/utils/message";
import request from "../../framework/common/utils/request";
import getInitiateFormData from "../../framework/common/utils/getInitiateFormData";
import BranchChoose from "./BranchChoose1";//分支步骤选择
import TemporaryStep from "./TemporaryStep1";//临时步骤编辑
import AuditorSortable from "./AuditorSortable1";//串行步骤编辑
import AuditorChoose from "./AuditorChoose1";//无人步骤选人
import { initStepData } from "./stepUtility";/*审批步骤数据清洗*/
import { NegotiateLogWrap } from "./components/NegotiateLogWrap";
import { scrollTo } from "../../framework/common/utils";
import eventBus, { useSubscribe } from "../../framework/common/eventBus";
/**
 * 步骤信息
 * step:{
 *  needChoose: 0 //值为1时，存在不确定的审批人选择。但是以前的工作流里面是0为存在不确定的审批人，当后续步骤node有多个节点，NodeConfirm为0的时候，说明该步骤责任人不明确
 *  nodes:[] //该步骤的审批人信息
 *  stepAttrs:{
 *      handle_mode: 'Serial' //Serial串行 Parallel并行
 *      multi_type：'Multi' // Single单人步骤 Multi多人步骤
 *      archived_mode: 'Auto', // 归档方式：Auditor-处理人归档，Auto-系统自动归档 
 *      adjust_auditor: false, // 允许调整责任人 true是 | false否
 *      enable_sign: true, // 开启签章，true开启 | false没开启
 *      no_auditor_rules: ["SkipStep"] //一个数组，如果包含了SkipStep，表示无责任人自动跳过
 *      adjust_auditor: true, // 是否可调整责任方 true可 | false不可
 *      adjust_multi_auditor: true, //调整责任人是否可选择多人 true | false
 *  }
 * }
 */

/**
 * props {}
 * tplData
 * params
 * urlPrefix
 * model edit编辑 readonly只读
 * actual_steps 实际的步骤路径，不包含branch确认步骤，返回给后端
 * approveSteps 步骤信息，包含branch确认步骤，展示在界面
 * setLoading 触发父组件loading，用于给确定按钮加loading状态
 * validateResult 首次加载步骤时的错误信息
 * setActual_steps 父组件更新actual_steps步骤信息的状态方法
 * setAllSteps 父组件更新approveSteps步骤信息的状态方法
 * showValidate 显示步骤校验错误信息
 */
 export default function (props) {
    if(!props?.approveSteps?.length){
        return <>
            <Skeleton active />
        </>
    }
    // const injectInfo= useInject()
    //组件依赖数据
    let tplData= props.tplData || {};
    let params = props.params || {};
    let model = props.model || "readonly"; 
    let urlPrefix = props.urlPrefix || null; 
    let showValidate = props.showValidate;
    const updater = useUpdate();
    const approveStepsRef= useRef(props.approveSteps || [])
    let approveSteps = approveStepsRef.current;//完整的步骤，包含branch，用于渲染在界面
    const validateResultRef = useRef(props.validateResult || null)
    let validateResult = validateResultRef.current;//步骤校验信息

    const actual_stepsRef= useRef(props.actual_steps || [])
    let actual_steps = actual_stepsRef.current;//不包含branch，用于返回给后端
    let selectStepId = useRef(null);//选中的步骤id
    
    //更新步骤信息
    window._stepsPath = actual_steps;//iframe流程图需要的流程信息
    function updataSteps({
        approveSteps,
        actual_steps
    }){
        approveStepsRef.current = approveSteps;
        actual_stepsRef.current = actual_steps;
        props.setActual_steps && props.setActual_steps(actual_steps);
        props.setAllSteps && props.setAllSteps(approveSteps);

        //重置流程路径选中的步骤id
        if(selectStepId.current){
            let hasSelectStep = actual_steps.find(function(item){
                return item.id === selectStepId.current;
            });//在最新的步骤内，找是否存在已选择过的步骤id
            if(hasSelectStep){
                //最新步骤内存在已选的步骤id，不做响应
            }else{
                //已有步骤内不存在已选择过的步骤，说明切换分支后，已选过的不做被清掉了
                //1.清空window对象内的缓存，调用流程图更新时，不会做选中操作
                window._selectrdStepId = null;
                //2.清空组件内的选中标记，更新后的流程图不会有选中效果
                selectStepId.current = null;
            }
        }

        //更新iframe依赖的流程信息
        window._stepsPath = actual_steps;
        eventBus.publish("handlestepsPath,update");
    }
    
    //流程路径滚动到指定步骤
    useSubscribe("scrollFlowPathView.update", (data)=>{
        scrollTo({
            scrollItemClass: '.steps_item[data-key="' + data.stepId + '"]',
            contentClass: ".js-steps_wrap"
        });
        selectStepId.current = data.stepId;
        updater();
    })

    if (!approveSteps) {
        return null;
    }

    /*步骤信息数据清洗-只读模式才做*/
    function renderApproveContent(){
        var steps = [];
        approveSteps.forEach(function(step){
            if(step.sub_process_instance && step.sub_process_instance.steps && step.sub_process_instance.steps.length){
                step.sub_process_instance.steps.forEach(function(s_step){
                    steps.push(s_step);
                });
            }else{
                steps.push(step);
            }
        });
        
        steps.forEach(function(step,i){
            //处理匿名
            var anonymous_approval = step.anonymous_approval,
                CurUserGUID = tplData.CurUserGUID,
                parent_auditor_id = tplData.NodeInfo.parent_auditor_id;
            if((step.nodes && step.step_define_id != (tplData.StepInfo && tplData.StepInfo.step_define_id) && anonymous_approval && anonymous_approval.Enable && JSON.parse(anonymous_approval.Scopes).length && anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1) && step.step_type != 2){
                step.nodes.forEach(function(node){
                    if(node.handle_id == CurUserGUID || (!node.handle_id && node.auditor_id == CurUserGUID) || (parent_auditor_id && (parent_auditor_id == node.handle_id || (!node.handle_id && node.auditor_id == parent_auditor_id)))){
                        step.CurUserIsPart = true;
                        step.nodesLength = step.nodes.length;
                        anonymous_approval.Scopes && JSON.parse(anonymous_approval.Scopes).length == 6 && (step.nodes = [node]);
                    }
                });
            }
        });
        approveSteps = steps;
        //approveSteps.reverse(); 
        var urlParams = getQuery();
        var open_type = urlParams.open_type;
        tplData.ParentProcess = params.ParentProcess;
        // 相关流程进来的隐匿逻辑按不按步骤处理
        if(open_type && open_type == 'monitor'){
            tplData.StepInfo && (tplData.StepInfo.step_define_id = '');
            tplData.StepInfo && (tplData.StepInfo.step_type = '');
        }

    }
    if(model === "readonly"){
        renderApproveContent();//只读模式需要对approveSteps进行数据清洗
    }
    let actual = approveSteps;//用于展示在页面上的步骤信息

    

    //返回步骤icon
    //对应原模板 jstemp-approve-steps-icon
    function jstempApproveStepsIcon(options){
        let status = options.status;
        let item = options.item;
        if (item
            && tplData
            && !tplData.ParentProcess
            && tplData.StepInfo.step_type != 2
            && !(item.CurUserIsPart && item.nodesLength == 1)
            && item.step_define_id != tplData.StepInfo.step_define_id
            && item.anonymous_approval && item.anonymous_approval.Enable
            && item.anonymous_approval.Scopes.indexOf('"operate"') != -1
            && item.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1
        ){
            return <>
                <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                <i data-class="icon-guanbi" className="line_icon iconfont icon-renmingbeijingtu text-color-c7cac7">
                    <i className="iconfont icon-yinni"></i>
                </i>
            </>
        }else{
            if (status == -3){
                return <>
                    <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                    <i data-class="icon-guanbi" className="line_icon iconfont icon-bohui text-color-f86161"></i>
                </>
            }

            if (status == -2){
                return <>
                    <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                    <i data-class="icon-guanbi" className="line_icon iconfont icon-zuofei text-color-f86161"></i>
                </>
            }

            if(status == -1){
                return <>
                    <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                    <i data-class="icon-guanbi" className="line_icon iconfont icon-zhongzhi1 text-color-f86161"></i>
                </>
            }

            if(status == 0){
                if(item && item.approval_rights && item.approval_rights.indexOf('Vote') != -1 
                    && (item.stepAttrs.handle_mode != 'Serial' || [1,2].indexOf(item.nodes[(item.nodesLength || item.nodes.length) - 1].node_status) != -1)){
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-renmingbeijingtu text-color-c7cac7">
                            <i className="iconfont icon-biaojue"></i>
                        </i>
                    </>
                }else{
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-shenpizhong text-color-c7cac7"></i>
                    </>
                }
            }

            if (status == 1){
                if(item && item.approval_rights && item.approval_rights.indexOf('Vote') != -1 && (item.stepAttrs.handle_mode != 'Serial' || [1,2].indexOf(item.nodes[(item.nodesLength || item.nodes.length) - 1].node_status) != -1)){
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-renmingbeijingtu text-color-ff8800">
                            <i className="iconfont icon-biaojue"></i>
                        </i>
                    </>
                }else{
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-shenpizhong text-color-ff8800"></i>
                    </>
                }
            }

            if(status == 2){
                if(item && item.approval_rights && item.approval_rights.indexOf('Vote') != -1 && (item.stepAttrs.handle_mode != 'Serial' || [1,2].indexOf(item.nodes[(item.nodesLength || item.nodes.length) - 1].node_status) != -1)){
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-renmingbeijingtu text-color-ff8800">
                            <i className="iconfont icon-biaojue"></i>
                        </i>
                    </>
                }else{
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-shenpizhong text-color-ff8800"></i>
                    </>
                }
            }

            if(status == 3){
                if(item && item.voted_status){
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className={"line_icon iconfont icon-renmingbeijingtu " + (item.voted_status == 1 ? "text-color-44b549" : "text-color-f86161")}>
                            {
                                item.voted_status == 1 
                                && <i className="iconfont icon-biaojue-tongyi"></i>
                            }
                            {
                                item.voted_status == 2
                                && <i className="iconfont icon-biaojue-butongyi"></i>
                            }
                        </i>
                    </>
                }else{
                    return <>
                        <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="line_icon iconfont icon-yishenpi text-color-44b549"></i>
                    </>
                }
            }
            
            if(status == 100){
                return <>
                    <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                    <i data-class="icon-guanbi" className="line_icon iconfont icon-shuo text-color-f86161"></i>
                </>
            }

            if( status == 998){
                return <>
                    <i className="line_icon_bg iconfont icon-renmingbeijingtu"></i>
                    <i data-class="icon-guanbi" className="line_icon iconfont icon-duobianxing text-color-c7cac7 text-20px top-9px -left-33px"></i>
                </>
            }
        }

    }

     function node_auditors_thumb(item){
        if(item.close_node_auditors_thumb){
            return <Tooltip getPopupContainer={() => document.querySelector(".main-content")} 
                color="white"
                overlayClassName="mytip" 
                placement="bottomRight" 
                title={item.close_node_auditors}>
                    <span className="approve_rule node_auditors_thumb" data-user={item.close_node_auditors}>{item.close_node_auditors_thumb}</span>
            </Tooltip>
        }else{
            return null;
        }
    }


    //对应原模板 jstemp-approve-steps-auditor
    function jstempApproveStepsAuditor(options){
        let item = options.item;
        let ind = options.ind;
        let step_type = options.step_type;
        if(item.auditor_name){
            return <div className="auditor_info">
                <div className="auditor_tx">
                    <i className="name_bg iconfont icon-renmingbeijingtu" style={{"color": item.__auditorColor__}}></i>{/*__auditorColor__ 是初始化数据清洗内给的头像颜色*/}
                    <span className="auditor_tx_name">{renderName(item.auditor_name)}</span>
                </div>
                <div className="auditor_main">
                    <div>
                        <span className="auditor_name">
                            {
                                item.auditor_name
                            }
                            {
                                step_type == 1
                                && "（发起）"
                            }
                            {
                                step_type == 2
                                && "（归档）"
                            }
                        </span>
                        {
                            (step_type == 1 && tplData && item.auditor_id != tplData.CurUserGUID)
                            &&
                            <span className="cancel_type">{tplData.CurUserName}代为发起</span>
                        }
                    </div>
                    {
                        (item.station_name && step_type == 1)
                        && <p className="auditor_dp">{item.station_name}</p>
                    }
                </div>
            </div>
        }else{
            return null;
        }
    }

    //串行
    //对应原模板 jstemp-approve-auditor-order
    function jstempApproveAuditorOrder(options){
        let item = options.item;//stpe.nodes 当前步骤的责任人
        let step = options.step;//当前步骤
        let path = options.path;
        let adjust_auditor_order = options.adjust_auditor_order;
        let p_path = options.p_path;
        let index = options.index;
        let step_type = options.step_type;

        return <AuditorSortable
                    key={step.name}
                    nodes={item}
                    onNodesChange={onNodesChange}
                    adjust_auditor_order={adjust_auditor_order}
                    p_path={p_path}
                    index={index}
                    path={path}
                    jstempApproveStepsAuditor={jstempApproveStepsAuditor}
                    step_type={step_type}
                    updater={updater}
                    step={step}
                    actual_steps={actual_steps}
                ></AuditorSortable>
    }

    //选人-单人步骤配置多人时，需要选择一个明确的人
    //对应原模板 jstemp-approve-auditor-choose
    function jstempApproveAuditorChoose(options){
        let nodes = options.item;
        let step_type = options.step_type;
        let path = options.path;
        let value = '';//默认值
        let currentStep = options.currentStep;
        nodes.find(function(nodeItem){
            if(nodeItem.Checked == 1){
                value = nodeItem.auditor_id;
                return true;
            }
        });//当前选中的责任人id作为默认值

        return <Radio.Group 
                className="choose_auditor_wrap"
                onChange={(e)=>{
                    nodes.map(function(node,index){
                        if(index === e.target['data-nodeind']){//根据选中的索引，更改选中的责任人
                            node.Checked = 1;
                        }else{
                            node.Checked = 0;
                        }
                    });

                    var p_step = actual_steps.find(function(s) {
                        return s.id == currentStep.id;
                    })
                    p_step.nodes = JSON.parse(JSON.stringify(nodes));

                    updater();
                }}
                value={value}>
                    {
                        nodes.map(function(node, ind){
                            return <Radio 
                                key={node.auditor_id}
                                data-key={node.auditor_id}
                                value={node.auditor_id}
                                data-path={path+'.nodes.'+ind}
                                data-step={path}
                                data-nodeind={ind}
                                className="re-select"
                                >
                                    {jstempApproveStepsAuditor({item:node,step_type:step_type,ind:ind})}
                                </Radio>
                        })
                    }
            </Radio.Group>
    }

    //checkbox change事件-并行/串行 多人时选择责任人
    function onNodesChange({e, nodes, step}){
        nodes.map(function(nodeItem){
            if(e.indexOf(nodeItem.auditor_id) > -1){
                nodeItem.Checked = true;
            }else{
                nodeItem.Checked = false;
            }
        });
        let p_step = actual_steps.find(function(s) {
            return s.id == step.id;
        });
        p_step.nodes = JSON.parse(JSON.stringify(step.nodes));//同步更新 actual_steps
        updater();
    }

    //对应原模板 jstemp-approve-auditor-and
    //多人并行
    function jstempApproveAuditorAnd(options){
        let item = options.item;//step.nodes 当前步骤所有审批人
        let step = options.step;//当前步骤
        let path = options.path;
        let step_type = options.step_type;

        if(step.stepAttrs.adjust_multi_auditor && path != 0){//允许调整责任人，且不是第一个步骤
            let checkedList = [];
            item.map(function(nodeItem){
                if(nodeItem.Checked){//tplData.ProcessInfo.MultiUserSelect
                    checkedList.push(nodeItem.auditor_id);
                }
            });

            /*可编辑模式下，展示CheckBox */
            return <Checkbox.Group
                    value={checkedList}
                    onChange = {
                        (e)=>{
                            onNodesChange({
                                e: e,
                                nodes: item,
                                step: step
                            }
                        )}
                    }
                    className="auditor_and_wrap">
                    {
                        item.map(function(node, ind){
                            return <div className="inline-block mr-1 mt-10px" 
                                data-key={node.auditor_id}
                                key={node.auditor_id}>
                                <Checkbox
                                    value={node.auditor_id}
                                    data-nodeind={ind}
                                >
                                    {
                                        /*审批人头像和名字信息*/
                                        jstempApproveStepsAuditor({item:node,step_type:step_type,ind:ind})
                                    }   
                                </Checkbox>
                                {
                                    /*这个是 + 号*/
                                    (ind < item.length - 1)
                                    && <div className="and_icon"></div>
                                }
                            </div>
                        })   
                    }
            </Checkbox.Group>
        }else{
            //不可调整责任人，直接返回头像和名字
            return <ul className="auditor_and_wrap">
                {
                    item.map(function(node, ind){
                        return <li 
                                data-key={node.auditor_id}
                                key={node.auditor_id}
                            >
                            {
                                /*审批人头像和名字信息*/
                                jstempApproveStepsAuditor({item:node,step_type:step_type,ind:ind})
                            }
                            {
                                (ind < item.length - 1)
                                && <div className="and_icon"></div>
                            }
                        </li>
                    })   
                }
            </ul>
        }

        
    }

    //返回步骤名称
    //对应原模板 jstemp-run-step-name
    function jstempRunStepName(item){
        // item.close_node_auditors_thumb = "张三、李四"
        // item.close_node_auditors = "张三、李四、王五"
        if(!tplData.ParentProcess
            && tplData.StepInfo.step_type != 2
            && !(item.CurUserIsPart && item.nodesLength == 1)
            && item.step_define_id != tplData.StepInfo.step_define_id
            && item.anonymous_approval && item.anonymous_approval.Enable
            && item.anonymous_approval.Scopes.indexOf('"operate"') != -1
            && item.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1){
            return <>
                <div className="step_name"><span className="state anon_approve">已隐匿</span>{item.name}
                    {node_auditors_thumb(item)}
                </div>
            </>
        }else{
            //这里可以精简代码
            if(item.status == -3 || item.status == -2 || item.status == -1){
                return <>
                    <div className="step_name"><span className="state approve_back">{item.status_text}</span>{item.name}
                        {node_auditors_thumb(item)}
                        {
                            item.overview
                            && <span className="approve_rule">{item.overview}</span>
                        }
                    </div>
                </>
            }
            
            if(item.status == 0){
                return <>
                    <div className="step_name"><span className="state inactive_approve">{item.status_text}</span>{item.name}
                        {node_auditors_thumb(item)}
                        {
                            item.overview
                            && <span className="approve_rule">{item.overview}</span>
                        }
                    </div>
                </>
            }
            
            if(item.status == 1 || item.status == 2){
                return <>
                    <div className="step_name"><span className="state wait_approve">{item.status_text}</span>{item.name}
                        {node_auditors_thumb(item)}
                        {
                            item.overview
                            && <span className="approve_rule">{item.overview}</span>
                        }
                    </div>
                </>
            }

            if(item.status == 3 && item.step_type != 1){
                return <>
                    <div className="step_name"><span className={"state " + (item.voted_status == 2 ? "approve_back" : "approved")}>{item.status_text}</span>{item.name}
                        {node_auditors_thumb(item)}
                        {
                            (
                                item.overview 
                                && !(item.stepAttrs.no_auditor_rules 
                                    && item.stepAttrs.no_auditor_rules.indexOf('SkipStep') != -1 
                                    && item.nodes[0].auditor_id == '00000000-0000-0000-0000-000000000000')
                            ) && <span className="approve_rule">{item.overview}</span>
                        }
                    </div>
                </>
            }
        }
    }

    function renderName (name) {
        var userName = '';
        if(name){
            if(/^[\u4e00-\u9fa5]/.test(name)){
                if(name.length > 3){
                    userName = name.substr(0,2);
                }else if(name.length == 3){
                    userName = name.substr(1);
                }else{
                    userName = name.substr(0,2);
                }
            }else{
                userName = name.substr(0,2);
            }
        }
        return userName;
    }

    //对应原模板 jstemp-approve-steps-tx-icon
    function jstempApproveStepsTxIcon(status, voted_status, stepItem, n_ind, tplData, item){
        if(stepItem
            && tplData
            && !tplData.ParentProcess
            && tplData.StepInfo.step_type != 2
            && !(stepItem.CurUserIsPart || ((item.handle_id || item.auditor_id) == tplData.CurUserGUID))
            && stepItem.step_define_id != tplData.StepInfo.step_define_id
            && stepItem.anonymous_approval && stepItem.anonymous_approval.Enable
            && stepItem.anonymous_approval.Scopes.indexOf('"operate"') != -1
            && stepItem.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1){
            return <>
                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                <i data-class="icon-guanbi" className="state_icon iconfont icon-renmingbeijingtu text-color-c7cac7">
                    <i className="iconfont icon-yinni"></i>
                </i>
            </>
        }else{
            return <>
                {
                    status == -3
                    &&<>
                        <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="state_icon iconfont icon-bohui text-color-f86161"></i>
                    </>
                }
            
                {
                    status == -2
                    &&<>
                        <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="state_icon iconfont icon-zuofei text-color-f86161"></i>
                    </>
                }
            
                {
                    status == -1
                    &&<>
                        <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                        <i data-class="icon-guanbi" className="state_icon iconfont icon-zhongzhi1 text-color-f86161"></i>
                    </>
                }
                {
                    status == 0
                    &&<>
                        {
                            (stepItem && stepItem.approval_rights && stepItem.approval_rights.indexOf('Vote') != -1 && ((stepItem.stepAttrs.handle_mode != 'Serial' && item.node_type != 13) || n_ind == stepItem.nodes.length - 1))
                            ? <>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-renmingbeijingtu text-color-c7cac7">
                                    <i className="iconfont icon-biaojue"></i>
                                </i>
                            </>
                            : <>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-shenpizhong text-color-c7cac7"></i>
                            </>
                        }
                    </>
                }

                {
                    status == 1
                    &&<>
                        {
                            (stepItem && stepItem.approval_rights && stepItem.approval_rights.indexOf('Vote') != -1 && ((stepItem.stepAttrs.handle_mode != 'Serial' && item.node_type != 13) || n_ind == stepItem.nodes.length - 1))
                            ?<>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-renmingbeijingtu text-color-ff8800">
                                    <i className="iconfont icon-biaojue"></i>
                                </i>
                            </>
                            :<>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-shenpizhong text-color-ff8800"></i>
                            </>
                        }
                    </>
                }

                {
                    status == 2
                    &&<>
                        {
                            (stepItem && stepItem.approval_rights && stepItem.approval_rights.indexOf('Vote') != -1 && ((stepItem.stepAttrs.handle_mode != 'Serial' && item.node_type != 13) || n_ind == stepItem.nodes.length - 1))
                            ?<>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-renmingbeijingtu text-color-ff8800">
                                    <i className="iconfont icon-biaojue"></i>
                                </i>
                            </>
                            :<>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-shenpizhong text-color-ff8800"></i>
                            </>
                        }
                    </>
                }

                {
                    status == 3
                    &&<>
                        {
                            voted_status
                            ?<>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className={"state_icon iconfont icon-renmingbeijingtu " + (voted_status == 1 ? "text-color-44b549" : "text-color-f86161")}>
                                    {
                                        voted_status == 1
                                        && <i className="iconfont icon-biaojue-tongyi"></i>
                                    }
                                    { 
                                        voted_status == 2
                                        && <i className="iconfont icon-biaojue-butongyi"></i>
                                    }
                                </i>
                            </>
                            :<>
                                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                                <i data-class="icon-guanbi" className="state_icon iconfont icon-yishenpi text-color-44b549"></i>
                            </>
                        }
                    </>
                }
            </>
        }
    }

    //返回审批列表责任人
    //对应原模板 jstemp-run-steps-auditor
    function getAuditorTx(attachments, item, step_type, path, ind, tplData, stepItem, index){

        //1.用户头像
        let auditor_tx_name = null;
        if(
            stepItem
            && !tplData.ParentProcess
            && tplData.StepInfo.step_type != 2
            && !stepItem.CurUserIsPart
            && stepItem.step_define_id != tplData.StepInfo.step_define_id
            && tplData && stepItem.anonymous_approval && stepItem.anonymous_approval.Enable
            && stepItem.anonymous_approval.Scopes.indexOf('"name"') != -1
            && stepItem.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1
        ){
            auditor_tx_name = <>
                <i className="name_bg iconfont icon-wurenyuan text-color-1990ff"></i>
            </>
        }else{
            let auditor_name = "";
            if(stepItem.step_type == 1 && stepItem.roll_back_type != 1){
                auditor_name = renderName(item.auditor_name);
            }else if(item.handle_name){
                auditor_name = renderName(item.handle_name);
            }else if(item.auditor_name){
                auditor_name = renderName(item.auditor_name);
            }
            auditor_tx_name =<>
                <i className={"name_bg iconfont icon-renmingbeijingtu " + ['text-color-1990ff','text-color-f5a623','text-color-01d4a9'][ind%3]}></i>
                <span className="auditor_tx_name">{auditor_name}</span>
            </>
        }

        //2.用户背景
        let tx_icon = null;
        if( item.add_sign_users_text){
            tx_icon = <>
                <i className="tx_icon_bg iconfont icon-renmingbeijingtu"></i>
                <i data-class="icon-guanbi" className="state_icon iconfont icon-renmingbeijingtu text-color-44b549"><span className="add_sign_icon">+</span></i>
            </>
        }else{
            tx_icon = <>
                {
                    jstempApproveStepsTxIcon(item.node_status, item.voted_status, stepItem, ind, tplData, item)
                }
            </>
        }

        return <>
            {auditor_tx_name}
            {tx_icon}
        </>
    }
    function getAuditorMain(attachments, item, step_type, path, ind, tplData, stepItem, index){

        let handleStatue = "";
        if(tplData.ParentProcess
            || tplData.StepInfo.step_type == 2
            || stepItem.step_define_id == tplData.StepInfo.step_define_id
            || !stepItem.anonymous_approval || !stepItem.anonymous_approval.Enable
            || stepItem.anonymous_approval.Scopes.indexOf('"operate"') == -1
            || (tplData && stepItem.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) != -1)
        ){
            if (item.handle_mode == 6 || item.handle_mode == 7 || item.handle_mode == 8 || item.node_status == -2){
                handleStatue = "（作废）";
            }else if (
                (step_type == 1 && index === 0) && ((item.status == 1 && item.node_type != 13) 
                || ( item.is_end_task == 1))
            ){
                handleStatue = "（发起）";
            }else if (step_type == 2 && item.node_status == 3){
                handleStatue = "（归档）";
            }else if (item.handle_mode == 0 && item.node_status == 3 && item.voted_status != 2){
                if (item.expand_opinion){
                    handleStatue = "（" + item.expand_opinion + "）";
                }else{
                    handleStatue = "（同意）";
                }
            }else if (item.handle_mode == 0 && item.node_status == 3 && item.voted_status == 2){
                handleStatue = "（不同意）";
            }else if (item.handle_mode == 0 && item.node_status == -3 && item.roll_back_type == 1){
                handleStatue = "（驳回重走）";
            }else if (item.handle_mode == 0 && item.node_status == -3 && item.roll_back_type == 0){
                handleStatue = "（驳回不重走）";
            }
        }

        let expand_tag = null;
        if(
            stepItem
            && !tplData.ParentProcess
            && tplData.StepInfo.step_type != 2
            && !stepItem.CurUserIsPart
            && stepItem.step_define_id != tplData.StepInfo.step_define_id
            && tplData && stepItem.anonymous_approval && stepItem.anonymous_approval.Enable
            && stepItem.anonymous_approval.Scopes.indexOf('"opinion"') != -1
            && stepItem.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1
        ) {

        }else{
            //item.consults_unread = 3
            if(item['extends'] && item['extends'].length > 0){
                expand_tag = <Tooltip getPopupContainer={() => document.querySelector(".main-content")} 
                                color="white"
                                overlayClassName="mytip bottomRightsm" 
                                placement="bottomRight" 
                                overlayStyle={{"maxWidth":"760px"}}
                                title={<NegotiateLogWrap list={item.extends} consults_unread_ids={item.consults_unread_ids}></NegotiateLogWrap>}>
                                    <i className="iconfont icon-jilu expand_tag" data-path={path}>
                                        {
                                            //todo 需要确认 item.consults_unread 属性是怎么来的，另外需要补充tip隐藏后，发送请求更新 item.consults_unread
                                        }
                                        <span className={clsx( !item.consults_unread && "hide")}>
                                            {item.consults_unread}
                                        </span>
                                    </i>
                            </Tooltip>
            }
        }

        return <>
            {
                (item.handle_name || item.auditor_name)
                && <div className="inline-block" style={{"width": "530px"}}>
                    <div className="auditor_name">
                        <div className="auditor_name_text">
                            {
                                (step_type == 1 && stepItem.roll_back_type != 1)
                                ? item.auditor_name
                                : (item.handle_name || item.auditor_name)
                            }
                            {handleStatue}
                        </div>
                        {
                            (step_type == 1 && item.handle_id && (item.auditor_id != item.handle_id || item.handle_mode == 6))
                            && <span className="cancel_type">{item.handle_mode_text}</span>
                        }

                        {
                            (step_type != 1 && item.handle_name &&(item.handle_mode == 6 || item.handle_mode == 7 ||  item.handle_mode == 8 || (item.handle_name != item.auditor_name && item.handle_mode == 0)))
                            && <span className="cancel_type">{item.handle_mode_text}</span>
                        }
                        {
                            (item.node_type == 13)
                            && <span className="cancel_type">{getApproveBtnName("AddSign", "加签")}</span>
                        }
                    </div>
                    {
                        item.station_name
                        && <p className="auditor_dp">{item.station_name}</p>
                    }
                </div>
            }
            
            <div className="absolute top-0 right-0">
                <div className="time_wrap">
                    {
                        (item.cc_list && item.cc_list.length > 0 && item.opinion)
                        && <Tooltip getPopupContainer={() => document.querySelector(".main-content")} 
                                overlayClassName="mytip" 
                                color="white"
                                placement="bottomLeft" 
                                title={"抄送人："+ item.cc_list.map((item)=>{return item.auditor_name}).join("、")}>
                                    <span className="chaosongrenWrap" aaa="1" data-path={path+".cc_list"}>
                                        抄送人：{item.cc_list.map((item)=>{return item.auditor_name}).join("、")}
                                    </span>
                            </Tooltip>
                    }

                    {
                        (item.agent && item.opinion)
                        && <span className="read_state">[ {item.agent} ]</span>
                    }

                    {
                        (item.status_text)
                        && <span className="read_state">[ {item.active_time || ''} {item.status_text} ]</span>
                    }
                    
                    {
                        (index !== 0 && item.node_status != 0 && item.spend_time_display)
                        && <span className={"time_duration " + (item.timeout && "timeout")}>
                                <i className="iconfont icon-chaoshi"></i>
                                {item.spend_time_display}
                            </span>
                    }

                    {
                        (item.handle_on)
                        && <span className="handle_time">{item.handle_on.replace(/:\d+$/ig,'')}</span>
                    }
                </div>
                {expand_tag}
            </div>
        </>
    }

    //返回实际按钮名称
    function getApproveBtnName(approveType, btnText){
        if(!tplData.flowOperationNameMap){
            return btnText;
        }
        var text = btnText;
        tplData.flowOperationNameMap.find(function(item){
            if(item.eventName === approveType){
                text = item.operationName;
                return true;
            }
        });
        return text;
    }

    function getNegotiateLogWrap(attachments, item, step_type, path, ind, tplData, stepItem, index){
        if(stepItem
            && !tplData.ParentProcess
            && tplData.StepInfo.step_type != 2
            && !stepItem.CurUserIsPart
            && stepItem.step_define_id != tplData.StepInfo.step_define_id
            && tplData && stepItem.anonymous_approval && stepItem.anonymous_approval.Enable
            && stepItem.anonymous_approval.Scopes.indexOf('"opinion"') != -1
            && stepItem.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1
        ){
            return null;
        }else{
            if(item.extends_opinion && item.extends_opinion.length){
                return <>
                    <ul className="negotiate_log_wrap">
                        {
                            item.extends_opinion.map(function(item, index){
                                return <React.Fragment key={index}>
                                    {
                                        (item.node_type == 7 || (item.node_type == 2 && item.handle_name) || item.node_type == 12)
                                        &&<>
                                            <li className="log_item">
                                                <div className="log_title">
                                                    {
                                                        item.node_type == 7
                                                        && <p>【协商】{item.handle_name} 协商给 {item.consult_to_user}</p>
                                                    }
                                                    
                                                    {
                                                        item.node_type == 12
                                                        && <p>【{getApproveBtnName("Assigned", "交办")}】{item.handle_name} {getApproveBtnName("Assigned", "交办")}给 {item.assigned_to_user}</p>
                                                    }

                                                    {
                                                        (item.node_type == 2 && item.handle_name)
                                                        && <p>【回复协商】{item.handle_name} 回复协商给 {item.consult_replay_user}</p>
                                                    }

                                                    <span className="absolute top-0 right-0">
                                                        {
                                                            item.cc_list_ExtendsOpinion && item.cc_list_ExtendsOpinion.length>0
                                                            && <Tooltip getPopupContainer={() => document.querySelector(".main-content")}
                                                                    overlayClassName="mytip" 
                                                                    color="white"
                                                                    placement="bottomLeft" 
                                                                    title={"抄送人："+ item.cc_list_ExtendsOpinion.map(item=>item.auditor_name).join("、")}>
                                                                    <span className="chaosongrenWrap" aaa="1" data-path={path+".cc_list"}>
                                                                        抄送人：{item.cc_list_ExtendsOpinion.map(item=>item.auditor_name).join("、")}
                                                                    </span>
                                                                </Tooltip>
                                                        }
                                                        <span>[ {item.agent} ]</span>
                                                        <span>{item.handle_on.replace(/:\d+$/ig,'')}</span>
                                                    </span>
                                                </div>
                                                {
                                                    item.handle_name && item.opinion
                                                    && <>
                                                        <pre className="log_content">{item.opinion}</pre> 
                                                    </>
                                                }
                                            </li>
                                        </>
                                    }
                                </React.Fragment>
                            })
                        }
                    </ul>
                </>
            }
        }
    }

    function jstempRunStepsAuditor(attachments, item, step_type, path, ind, tplData, stepItem, index){
        return <>
            {
                (item.handle_name || item.auditor_name)
                &&<>
                    <div className="auditor_tx">
                        {getAuditorTx(attachments, item, step_type, path, ind, tplData, stepItem, index)}
                    </div>
                </>
            }
            <div className="auditor_main">
                {getAuditorMain(attachments, item, step_type, path, ind, tplData, stepItem, index)}
            </div>
            {
                (item.opinion || item.sign_img)
                &&<>
                    <div className="opinion_sign_img">
                        {
                            item.opinion
                            &&<>
                                <div className={"handle_text_wrap " + (!item.handle_name && "no_auditor")} style={{"width" : item.sign_img?"760px" :"970px"}}>
                                    <pre className="handle_text">{item.opinion}</pre>
                                    {
                                        item.add_sign_users_text
                                        &&<>
                                            <p className="add_sign_text">[ {getApproveBtnName("AddSign", "加签")}后{item.status == 3 ? '需要我再次确认' : '进入下一步审批'} ]</p>
                                            <Tooltip getPopupContainer={() => document.querySelector(".main-content")} 
                                                overlayClassName="mytip" 
                                                color="white"
                                                placement="bottomLeft" 
                                                title={item.add_sign_users_text}>
                                                    <p className="add_sign_text add_sign_text_tip">{item.add_sign_users_text}</p>
                                            </Tooltip>
                                        </>
                                    }
                                </div>
                            </>
                        }
                        {
                            item.sign_img
                            && <img className="sign_img" src={item.sign_img} alt="" />
                        }
                    </div>
                </>
            }
            {getNegotiateLogWrap(attachments, item, step_type, path, ind, tplData, stepItem, index)}
        </>;
    }
    
    //获取审批步骤item-只读模式
    function getStepItem(item, ind){
        if(
            (
                ind !== actual.length - 1 && 
                item.step_type == 2 && 
                [-3,-2,-1].indexOf(item.status) == -1
            ) || 
            (
                item.anonymous_approval.Scopes.indexOf('"allstep"') != -1 
                && item.step_define_id != tplData.StepInfo.step_define_id 
                && item.anonymous_approval 
                && item.anonymous_approval.Enable 
                && item.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1
            )
        ){
            return null;
        }else{
            let cls = "";
            if(item.step_type == 8){
                cls = "hidden "
            }
            if(ind==0){
                cls += "first "
            }
            if(ind==actual.length-1 && actual.length > 1){
                cls += "last "
            }
            if(
                tplData.StepInfo.step_type != 2 
                && item.step_define_id != tplData.StepInfo.step_define_id 
                && item.anonymous_approval 
                && item.anonymous_approval.Enable 
                && item.anonymous_approval.ExcludedActivityIds.indexOf(tplData.StepInfo.step_define_id) == -1 
                && item.anonymous_approval.Scopes.indexOf('"name"') != -1
                && item.anonymous_approval.Scopes.indexOf('"opinion"') != -1
                && item.anonymous_approval.Scopes.indexOf('"operate"') != -1
                && item.anonymous_approval.Scopes.indexOf('"org"') != -1
                && item.anonymous_approval.Scopes.indexOf('"operate_time"') != -1
                && item.anonymous_approval.Scopes.indexOf('"signature"') != -1
                && !item.CurUserIsPart
                && !tplData.ParentProcess
            ){
                return <li key={ind} className={"steps_item " + cls}>
                    <div className="item_main">
                        {
                            jstempApproveStepsIcon({status:item.status,item: item})
                        }
                        <div className="border_arrow"></div>
                        {
                            jstempRunStepName(item, tplData)
                        }
                        <div className="node_main">
                            <span className="text-color-666 text-13px">无权限查看！</span>
                        </div>
                    </div>
                </li>
            }else{
                if(
                    item.step_type == 8 
                    && item.voted_status == 2 
                    && item.stepAttrs 
                    && item.stepAttrs.converge_mode == 'Vote'
                ) {
                    if(item.step_type == 8){//特殊处理，这里=8时，class设置为空
                        cls = ""
                    }
                    return <li key={ind} className={"steps_item " + cls}>
                        <div className="item_main">
                            {
                                jstempApproveStepsIcon({status:-2})
                            }
                            <span className="voted_cancellation">
                                {item.nodes[0].opinion}
                            </span>
                        </div>
                    </li>
                } else{
                    let cls = "";
                    if(item.step_type == 8){
                        cls += "hidden "
                    }
                    if(ind==0){
                        cls += "first "
                    }
                    if(ind==actual.length-1 && actual.length > 1){
                        cls += "last "
                    }
                    return <>
                        <li key={ind} className={"steps_item " + cls}>
                            <div className="item_main">
                                {
                                    jstempApproveStepsIcon({status:item.status, item: item})
                                }
                                <div className="border_arrow"></div>
                                {
                                    jstempRunStepName(item, tplData)
                                }
                                {(item.nodes && item.nodes.length) && 
                                    <div className="node_main">
                                        {
                                            item.nodes.map(function(node, n_ind){
                                                return (
                                                    <div key={n_ind} className="clearfix auditor_info">
                                                        {
                                                            jstempRunStepsAuditor(item.attachments, node, item.step_type, ind+'.nodes.'+n_ind, n_ind, tplData, item, ind, )
                                                        }
                                                    </div>
                                                )
                                            })
                                        }
                                    </div>
                                    
                                }
                            </div>
                        </li>
                    </>
                }
            }
        }
    }

    //选择步骤分支
    /**
     * 
     * @param {*} stepInfo 
     * branchStepIndex 选中的分支步骤索引
     * stepIndex 当前步骤的索引
     */
    function chooseStep (stepInfo) {
        let stepIndex = stepInfo.stepIndex;//步骤索引
        let branchStepIndex = stepInfo.branchStepIndex;//选中的分支步骤索引
        var path = stepIndex + ".branch." + branchStepIndex;
        var branchStep = get(approveSteps, path);
        var branch = approveSteps[stepIndex].branch;
        branch.forEach(function(step, i) {
            step.nodes = null;
            step.needChoose = null;
            step.tag = null;
            step.chooseed = null;
        });
        branchStep.chooseed = true;
        var c_Step = approveSteps[stepIndex - 1];//当前分支步骤的上一个步骤
        var ind = 0;
        actual_steps.map(function(item, i) {//实际步骤
            if (item.id == c_Step.id) {//当前分支步骤的上一个步骤
                ind = i;
                item.toStepIds = [branchStep.id];//给一个toStepIds = 当前选中的分支步骤的id
            }
        });
        approveSteps.map(function(item, i) {//所有步骤
            if (item.id == c_Step.id) {//当前分支步骤的上一个步骤
                item.toStepIds = [branchStep.id];//给一个toStepIds = 当前选中的分支步骤的id
            }
        });

        let postObj = getInitiateFormData({
            params: params, 
            tplData: tplData, 
            approveType: props.approveType || "",//审批类型
            type: 'getBranchStep'
        });

        postObj['actual_steps'] = actual_steps.slice(0, ind + 1);
        postObj['choose_step_id'] = branchStep.id;
        setBranchLoading(true);//加载状态
        props.setLoading && props.setLoading(true);//父组件设置loading
        return request({
            url: "/flowinstance/process/choose-branch-step",
            method: "POST",
            data: postObj,
          }).then(
            function(resObj){
                setBranchLoading(false);
                props.setLoading && props.setLoading(false);//父组件设置loading
                if (resObj.code == 1 && resObj.data) {
                    
                    var cacheBranch = temporaryStepCache[branchStep.id];

                    //给选中的分支步骤信息进行赋值操作
                    var currChoosedStep = resObj.data.actual_steps[0];
                    branchStep.nodes = currChoosedStep.nodes;
                    branchStep.needChoose = currChoosedStep.needChoose;
                    branchStep.tag = currChoosedStep.tag;
                    branchStep.chooseed = true;

                    var nextStep = cacheBranch && cacheBranch.length ? cacheBranch : resObj.data.actual_steps.slice(0);//选中分支后的剩余步骤
                    nextStep = initStepData({
                        steps: nextStep,
                        multiUserSelect: tplData.ProcessInfo.MultiUserSelect
                    });

                    //更新所有步骤
                    var newApproveSteps = approveSteps.slice(0, stepIndex - 0 + 1);
                    newApproveSteps = newApproveSteps.concat(nextStep);

                    //不知道这里逻辑是干什么的
                    if (
                        currChoosedStep.needChoose && currChoosedStep.nodes.length == 0 
                        && (
                            currChoosedStep.stepAttrs 
                            && currChoosedStep.stepAttrs.no_auditor_rules 
                            && currChoosedStep.stepAttrs.no_auditor_rules.indexOf('SkipStep') == -1 
                            && !currChoosedStep.stepAttrs.adjust_auditor || currChoosedStep.step_type == 2
                            )
                        ) 
                    {
                        newApproveSteps[stepIndex].checkTip = true;
                    }

                    //返回的步骤依然包含分支信息，追加到末尾继续选
                    if (resObj.data.branch && resObj.data.branch.length) {
                        newApproveSteps.push({
                            branch: resObj.data.branch
                        });
                    }

                    var newActual_steps = [];//对应原属性 explicitStepsPath_module.actual_steps
                    newApproveSteps.map(function(item, i) {
                        if(item.id && !item.branch){
                            newActual_steps.push(item);//不知道这里逻辑干什么的
                        }
                    });

                    let newValidateResult = null;
                    if (resObj.data.validateResult) {
                        if (resObj.data.validateResult.errorCode == 30015) {
                            newValidateResult = resObj.data.validateResult;
                        }
                        if (resObj.data.validateResult.errorCode == 30012 || resObj.data.validateResult.errorCode == 30011) {
                            newValidateResult = "";
                        }
                    }

                    updataSteps({
                        approveSteps: newApproveSteps,//更新流程图 _this.refreshSteps();
                        actual_steps: newActual_steps
                    });//更新步骤

                    validateResultRef.current = newValidateResult;//更新错误信息
                    eventBus.publish("setStepHasNoError.update", newValidateResult);//父组件更新validateInfo，用于控制请求失败后，弹出框按钮显示为 “我知道了”

                    updater();
                } else {
                    message.info({
                        content: resObj.message,
                    });
                }
            },
            function(){
                setBranchLoading(false);
                props.setLoading && props.setLoading(false);//父组件设置loading
                message.info({
                    content: "获取分支信息失败",
                });
            }
        )
    }
    //删除临时步骤
    const [temporaryStepCache, setTemporaryStepCache] = useState({});
    function deleteTemporaryStep({dataPath}){
        var index = dataPath;
        var p_index = index;
        var step = approveSteps[index-0],previousStep = approveSteps[index-0-1];
        var p__prev_step = actual_steps.find(function(s) {
            return s.id == previousStep.id;
        });
        actual_steps.find(function(s,i) {
            if(s.id == step.id){
                p_index = i;
            }
            return s.id == step.id;
        })
        var toStepIds = step.toStepIds;
        previousStep.toStepIds = toStepIds;
        p__prev_step.toStepIds = toStepIds;

        if(previousStep.oldToStepIds+'' == toStepIds+''){
            previousStep.oldToStepIds = [];
            p__prev_step.oldToStepIds = [];
        }

        if(step.temporaryStep && step.temporaryStepToId){
            previousStep.temporaryStepToId = step.temporaryStepToId;
            p__prev_step.temporaryStepToId = step.temporaryStepToId;
        }

        //更新步骤的默认分支配置
        var default_transition_to_activity = step.default_transition_to_activity;
        // 只有在默认分支上新增临时步骤需要处理默认分支继承关系
        if(default_transition_to_activity && toStepIds.length == 1 && toStepIds[0] == default_transition_to_activity){
            previousStep.default_transition_to_activity = default_transition_to_activity;
            p__prev_step.default_transition_to_activity = default_transition_to_activity;
            step.default_transition_to_activity = '';
        }

        approveSteps.splice(index-0,1);
        actual_steps.splice(p_index,1);

        var leftInd = index-0-1,rightInd = index-0,leftGo = true,rightGo = true;

        while (leftGo || rightGo) {
            if(leftInd <= 0){
                leftGo = false;
            }else{
                if(approveSteps[leftInd].branch){
                    leftGo = false;
                }else{
                    leftInd--;
                }
            }

            if(rightInd >= approveSteps.length){
                rightGo = false;
            }else{
                if(approveSteps[rightInd].branch){
                    rightGo = false;
                }else{
                    rightInd++;
                }
            }

        }

        // 缓存新增的步骤
        if(rightInd != 0){
            var branchCacheStep = approveSteps.slice(leftInd+1,rightInd);
            if(branchCacheStep && branchCacheStep.length){
                temporaryStepCache[branchCacheStep[0].id] = branchCacheStep;
            }
        }
        
        updataSteps({
            approveSteps: approveSteps,//更新流程图 _this.refreshSteps();
            actual_steps: actual_steps
        });//更新步骤
        updater();//更新步骤信息_this.refreshSteps();
    }
    //添加临时步骤
    function addTemporaryStep({dataPath}){
        var index = dataPath;
        var p_index = dataPath;
        var id = 'new_' + (+new Date()) + '_' + (((1 + Math.random())*0x10000)|0).toString(16).substring(1);
        var step = approveSteps[index-0];
        //steps里存的是渲染确认路径交互的步骤数据，actual_steps存的是提交到后台的数据，两者数据格式可能不一样
        var p_step = {};
        actual_steps.forEach(function(s, i) {
            if(s.id == step.id){
                p_index = i;
            }
            if(s.id == step.id){
                p_step = s;
            }
        })
        var toStepIds = p_step.toStepIds;
        step.toStepIds = [id];
        p_step.toStepIds = [id];
        step.temporaryStepToId = step.toStepIds;
        p_step.temporaryStepToId = step.toStepIds;

        var temporaryStepToId = toStepIds;
        if(approveSteps[index-0+1] && approveSteps[index-0+1].branch){
            temporaryStepToId = [];
            approveSteps[index-0+1].branch.forEach(function(item){
                temporaryStepToId.push(item.id);
            });
        }

        if(!step.oldToStepIds || step.oldToStepIds.length == 0){
            step.oldToStepIds = temporaryStepToId;
            p_step.oldToStepIds = temporaryStepToId;
        }

        var _step = {
            stepAttrs:{multi_type:'Multi',handle_mode:'Serial'},
            name:'',
            nodes:[],
            id:id,
            temporaryStep:true,
            temporaryStepToId: temporaryStepToId,
            toStepIds:toStepIds
        };

        //更新步骤的默认分支配置
        var default_transition_to_activity = step.default_transition_to_activity;
        // 只有在默认分支上新增临时步骤需要处理默认分支继承关系
        if(default_transition_to_activity && toStepIds.length == 1 && toStepIds[0] == default_transition_to_activity){
            _step.default_transition_to_activity = default_transition_to_activity;
            step.default_transition_to_activity = '';
            p_step.default_transition_to_activity = '';
        }

        approveSteps.splice(index-0+1,0,_step);
        actual_steps.splice(p_index+1,0,_step);

        var leftInd = index-0,
            rightInd = index-0 + 1,
            leftGo = true,
            rightGo = true;

        while (leftGo || rightGo) {
            if(leftInd <= 0){
                leftGo = false;
            }else{
                if(approveSteps[leftInd].branch){
                    leftGo = false;
                }else{
                    leftInd--;
                }
            }

            if(rightInd >= approveSteps.length){
                rightGo = false;
            }else{
                if(approveSteps[rightInd].branch){
                    rightGo = false;
                }else{
                    rightInd++;
                }
            }
        }

        // 缓存新增的步骤
        if(rightInd != 0){
            var branchCacheStep = approveSteps.slice(leftInd+1,rightInd);
            if(branchCacheStep && branchCacheStep.length){
                temporaryStepCache[branchCacheStep[0].id] = branchCacheStep;
            }
        }

        updataSteps({
            approveSteps: approveSteps,//更新流程图 _this.refreshSteps();
            actual_steps: actual_steps
        });//更新步骤
        updater();
    }

    //获取审批步骤item-编辑模式
    const [branchLoading, setBranchLoading] = useState(false);//获取分支步骤状态
    function getEditStepItem(item, ind){
        let li = null;
        if(item.branch && item.branch.length){//需要选择分支

            //处理校验class
            let errorStepCls = "";
            if(
                showValidate //触发了步骤校验
            ){
                let hasCheckedBranch = item.branch.filter(function(itemNode){
                    return itemNode.chooseed == true;
                });
                if(hasCheckedBranch <= 0){//如果没有选中分支
                    errorStepCls = "errorStep checkTip";
                }
            }

            //步骤选择
            li = <>
                <div className="choose_step">请选择步骤</div>
                <li className={
                    clsx('steps_item choose_steps_item_wrap', 
                        item.step_type == 8 && 'none', 
                        ind == 0 && 'first', 
                        (ind == actual.length - 1 && actual.length > 1 && !validateResult) &&'last', 
                        errorStepCls)
                    }
                >
                    <div className="item_main">
                        {
                            jstempApproveStepsIcon({status: 998})
                        }
                        <div className="border_arrow"></div>
                        <Spin spinning={branchLoading}>
                            <BranchChoose 
                                onChange={chooseStep}
                                ind={ind}
                                item={item}
                                ></BranchChoose>
                        </Spin>
                    </div>
                </li>
            </>
        }else{
            if(item.temporaryStep){
                //处理校验class
                let errorStepCls = "";
                if(
                    showValidate //触发了步骤校验
                    &&(
                        item.nodes.length <= 0 //当前步骤没有nodes信息
                        || item.name.trim() === "" //当前步骤没有步骤名称
                    )
                ){
                    errorStepCls = "errorStep checkTip";//加上错误提示
                }
                li = <li className={clsx("steps_item canHoverStep temporaryStepWrap", errorStepCls)} data-id={item.id}>
                        {
                            /*临时步骤编辑表单*/
                        }
                        <TemporaryStep
                            parentUpdater={updater}
                            urlPrefix={urlPrefix}
                            item={item}
                            tplData={tplData}
                            params={params}
                            deleteTemporaryStep={deleteTemporaryStep}
                            ind={ind}
                            approveSteps={approveSteps}
                            actual_steps={actual_steps}
                            ></TemporaryStep>
                    </li>
            }else{
                //处理校验class
                let errorStepCls = "";
                if(
                    showValidate //触发了步骤校验
                    && item.nodes //当前步骤存在nodes信息
                    && item.step_type== 4 //当前步骤类型为未审批的步骤
                ){
                    if(item.nodes.length <= 0){//当前步骤没有解析到责任人
                        if(item.stepAttrs.no_auditor_rules.indexOf('SkipStep') < 0){//当前步骤无责任人不可跳过
                            errorStepCls = "errorStep checkTip";//加上错误提示
                        }
                    }
                    if(errorStepCls === "" && item.nodes.length > 0){//当前步骤存在审批责任人，且没有选中的责任人，就一定要校验选择至少1人
                        let hasCheckedNode = item.nodes.filter(function(itemNode){
                            return itemNode.Checked == true;
                        });
                        if(hasCheckedNode <= 0){//如果没有选中的责任人
                            errorStepCls = "errorStep checkTip";
                        }
                    }
                }

                if(
                    showValidate //触发了步骤校验
                    && item.step_type == 2 //当前步骤类型为归档步骤
                    && item.stepAttrs.archived_mode === "Auditor"//且为手动归档
                ){
                    let hasCheckedNode = item.nodes.filter(function(itemNode){
                        return itemNode.Checked == true;
                    });
                    if(hasCheckedNode <= 0){//如果没有选中的责任人
                        errorStepCls = "errorStep checkTip";
                    }
                }

                let stepsIcon = null;
                if(item.needChoose && item.nodes.length == 0 && (item.stepAttrs && item.stepAttrs.no_auditor_rules && item.stepAttrs.no_auditor_rules.indexOf('SkipStep') == -1 && !item.stepAttrs.adjust_auditor || (!item.stepAttrs.adjust_auditor && item.step_type == 2))){
                    stepsIcon = jstempApproveStepsIcon({status:100});
                }else if(item.status){
                    stepsIcon = jstempApproveStepsIcon({status: item.status, item: item});
                }else if(ind == 0){
                    stepsIcon = jstempApproveStepsIcon({status:1});
                }else{
                    stepsIcon = jstempApproveStepsIcon({status:0});
                }

                let person = null;
                if(item.__needChooseAuditor__){//步骤数据清洗，根据判断得到，只要有这个参数，就是需要选人
                    //当前步骤没解析到人，但是允许调整责任人，
                    person = <div className="person" key={item.id}>
                        <AuditorChoose 
                            parentUpdater={updater}
                            urlPrefix={urlPrefix}
                            step={item}
                            tplData={tplData}
                            params={params}
                            ind={ind}
                            actual_steps={actual_steps}></AuditorChoose>
                    </div>;
                }else if(item.nodes && item.nodes.length){
                    if(item.needChoose && item.nodes.length > 1){
                        //<!-- 单人出现多人 -->
                        person = jstempApproveAuditorChoose({item:item.nodes,step_type:item.step_type,path:ind, currentStep: item})
                    }else if(item.stepAttrs && item.stepAttrs.handle_mode == 'Parallel' && item.stepAttrs.multi_type == 'Multi'){
                        //<!-- 并行 -->
                        person = jstempApproveAuditorAnd({item:item.nodes,step_type:item.step_type,path:ind,step:item,tplData:tplData});
                    }else if(item.stepAttrs && item.stepAttrs.handle_mode == 'Serial' && item.stepAttrs.multi_type == 'Multi'){
                        //<!-- 串行 -->
                        person = jstempApproveAuditorOrder({index:ind,item:item.nodes,step_type:item.step_type,adjust_auditor_order:item.stepAttrs.adjust_auditor_order,path:ind+'.nodes',p_path:ind,step:item});
                    }else{
                        //<!-- 单人或多人 -->
                        person = <>
                            {
                                item.nodes.map(function(node, ind){
                                    return <div key={ind} style={{"marginTop": item.step_type != 1 ? "11px" : "0"}}>
                                        {
                                            jstempApproveStepsAuditor({item:node,step_type:item.step_type,ind:ind,tplData:tplData})
                                        }
                                    </div>
                                })
                            }
                        </>
                    }
                }

                let steps_tag = null;
                if(item.stepAttrs && item.stepAttrs.adjust_auditor && (item.stepAttrs.no_auditor_rules && item.stepAttrs.no_auditor_rules.indexOf('SkipStep') == -1 || item.stepAttrs.archived_mode == 'Auditor') && (!item.nodes || item.nodes.length == 0)){

                }else if((item.tag && item.step_type != 2) || (item.tag && item.needChoose == 1)){
                    steps_tag = <p className="mt-1 mb-1 steps_tag">{item.tag}</p>;
                }

                li = <li className={
                            clsx("steps_item", 
                                props.canShowFlowMap && "canHoverStep",//开启展开流程图
                                errorStepCls, //校验报错状态
                                item.step_type == 8 && "none",
                                ind == 0 && "first",
                                item.id === selectStepId.current && "active",//选中的流程id
                                (ind == actual.length - 1 && actual.length > 1 && !validateResult) && "last",
                                (item.needChoose && item.nodes.length == 0 && (item.stepAttrs && item.stepAttrs.no_auditor_rules && item.stepAttrs.no_auditor_rules.indexOf('SkipStep') == -1 || item.step_type == 2)) && "checkTip"
                            )
                         }
                         key={item.id}
                         data-key={item.id}
                         onClick={
                            function(){
                                //展示流程图时，才响应点击操作
                                if(props.canShowFlowMap === true){
                                    //点击步骤时，联动定位流程图
                                    window._selectrdStepId = [item.id];
                                    eventBus.publish("selectFlowMapStep.update");
                                    selectStepId.current = item.id;
                                    updater();
                                }
                            }
                        }
                     >
                        <div className="item_main">
                            {stepsIcon}
                            <div className="border_arrow"></div>
                            {
                                item.step_type != 1
                                && <div className="step_name">
                                        {
                                            item.step_type == '5'
                                            && <i className="iconfont icon-ziliu subProcessTag"></i>
                                        }
                                        {
                                            (item.tag && item.step_type == 2 && item.needChoose != 1)
                                            ? item.tag
                                            : <>
                                                {
                                                    (!item.is_Adjustment && item.stepAttrs && item.stepAttrs.multi_type == 'Multi' && item.stepAttrs.adjust_multi_auditor && item.nodes && item.nodes.length && item.is_user_reset_activity != 1 && ind != 0)
                                                    ? <>
                                                        {/*多人步骤 并且允许调整责任人时，要有全选/全不选Checkbox，被控制的全选CheckBox组，在下面的 person 组件内*/}
                                                        <Checkbox 
                                                            className="adjust_multi_auditor" 
                                                            data-path={ind}
                                                            indeterminate={(()=>{
                                                                if(item?.nodes?.length > 0){//当前步骤存在审批责任人，且责任人全选
                                                                    let checkedNodes = item.nodes.filter(function(itemNode){
                                                                        return itemNode.Checked === true;
                                                                    })
                                                                    return checkedNodes.length > 0 && checkedNodes.length != item.nodes.length;//勾选数量大于0且小于总人数，设置半选
                                                                }else{
                                                                    return false;
                                                                }
                                                            })()}
                                                            checked={(()=>{
                                                                if(item?.nodes?.length > 0){//当前步骤存在审批责任人，且责任人全选
                                                                    return item.nodes.every(function(itemNode){
                                                                        return itemNode.Checked === true;
                                                                    })
                                                                }else{
                                                                    return false;
                                                                }
                                                            })()}
                                                            onChange={(e)=>{
                                                                item?.nodes && item.nodes.map(function(itemNode){
                                                                    itemNode.Checked = e.target.checked;
                                                                })//设置全选反选
                                                                let p_step = actual_steps.find(function(s) {
                                                                    return s.id == item.id;
                                                                });
                                                                p_step.nodes = JSON.parse(JSON.stringify(item.nodes));//同步更新 actual_steps
                                                                updater();
                                                            }}
                                                            >
                                                                {item.name}
                                                            </Checkbox>
                                                    </>
                                                    : <>
                                                        {/*不是多人步骤直接显示步骤名称*/}
                                                        {item.name}
                                                    </>
                                                }
                                            </>
                                        }
                                </div>
                            }

                            {person}
                            {steps_tag}
                        </div>
                    </li>
            }

            if((tplData.temporaryStepsSetting && 
                (tplData.ApproveSteps.length ? tplData.temporaryStepsSetting.approve : tplData.temporaryStepsSetting.initiated) && 
                actual[ind+1] && item.step_type != 8)
            ){
                /*添加临时步骤 */
                li = <>
                    {li}
                    <li 
                        className="addTemporaryStep" 
                        onClick={
                            ()=>{
                                addTemporaryStep({
                                    dataPath: ind
                                });
                            }
                        }
                        data-path={ind}>
                            <i className="iconfont icon-tianjia" style={{"fontSize": "14px", "color":"#1990FF"}}></i>
                            添加步骤
                    </li>
                </>
            }
        }
        return li
    }

    // todo 需要实现的提示交互
    /*
    var _this = this;
            // 拓展节点tip
            $.each($('.expand_tag'), function(i, item) {
                var path = $(this).attr('data-path');
                var node = explicitStepsPath_module.getPathData(tplData.ApproveSteps, path),
                    list = node['extends'];
                if (node.consults_unread_ids && node.consults_unread_ids.length && node.consults_unread) {
                    _this.expand_tag.list = list;
                    $(this).addClass('curr_node').find('span').removeClass('hide').text(node.consults_unread);
                    _this.expand_tag.activeTag = new tip({
                        event: "mouseover",
                        direction: "bottomRight",
                        $dom: $(item),
                        offset: 20,
                        maxWidth: "760px",
                        target: $("body"),
                        class: 'expand_tag_content',
                        isHtml: true,
                        content: template('jstemp-negotiate-log', { list: list, consults_unread_ids: node.consults_unread_ids }),
                        callback: function() {
                            $(item).addClass('active');
                        },
                        hideCallback: function() {
                            negotiate_module.consultRead();
                            $(item).removeClass('active');
                        }
                    });
                } else {
                    new tip({
                        event: "mouseover",
                        direction: "bottomRight",
                        $dom: $(item),
                        offset: 20,
                        maxWidth: "760px",
                        target: $("body"),
                        class: 'expand_tag_content',
                        isHtml: true,
                        content: template('jstemp-negotiate-log', { list: list, consults_unread_ids: node.consults_unread_ids }),
                        callback: function() {
                            $(item).addClass('active');
                        },
                        hideCallback: function() {
                            $(item).removeClass('active');
                        }
                    });
                }
            });
     */
            
    return <>
        {
            model === "readonly"
            ? <div id="approveList">{/*只读模式 */}
                <div className="cell_title"> 审批意见
                <Operations></Operations>
                </div>
                <div id="approveContent">
                    <div className="steps_wrap">
                        <ul className="steps_conent">
                            {
                                //遍历步骤信息
                                actual.map(function(item, ind){
                                    return <React.Fragment key={ind}>
                                        {getStepItem(item, ind)}
                                    </React.Fragment>;
                                })
                            }
                        </ul>
                    </div>
                </div>
            </div>
            :<div className="edit-steps_wrap js-steps_wrap">
                <div className="steps_wrap">{/*编辑模式 */}
                    <ul className="relative steps_conent">
                        {
                            //遍历步骤信息
                            actual.map(function(item, ind){
                                return <React.Fragment 
                                    key={item.id ? item.id : ind}>
                                    {getEditStepItem(item, ind)}
                                </React.Fragment>;
                            })
                        }
                        {
                            validateResult
                            && <li className="steps_item last errorStep checkTip">
                                    <div className="item_main">
                                        
                                        {
                                            jstempApproveStepsIcon({status:100})//{{include 'jstemp-approve-steps-icon' ({status:100})}}
                                        }
                                        <div className="border_arrow"></div>
                                        <p className="mt-1 mb-1 steps_tag">{validateResult.message}</p>
                                    </div>
                                </li>
                        }
                    </ul>
                </div>
            </div>
        }
        </>;
 }